Bogota car accidents 2014

library(tidyverse)
library(lubridate)

Data import

Data downloaded from https://docs.google.com/spreadsheets/d/1lgR-UpR9v9lmtoeK1ZhlVfs0FBj1xXz_eImhcrSI4Q0/

accidents_raw <- read_csv("data/Car_Accidents_2014_Bogota.csv")
Parsed with column specification:
cols(
  the_geom = col_character(),
  cartodb_id = col_integer(),
  codigo_accidente = col_integer(),
  fecha_ocurrencia = col_date(format = ""),
  hora_ocurrencia = col_character(),
  gravedad = col_character(),
  objectid = col_integer(),
  localidad = col_character(),
  municipio = col_character(),
  x = col_double(),
  y = col_double(),
  timedate = col_datetime(format = ""),
  clase = col_character()
)
accidents_raw
# Odd to have exactly 10000 rows, if the dataset is supposed to be complete
  • the_geom : geom
  • cartodb_id : reference#
  • codigo_accidente : Accident code from police ?
  • fecha_ocurrencia eg. 2014-10-29 : Date
  • hora_occurencia eg. 14:10:00 : Time
  • gravedad : Gravity (severity)
  • objectid : reference#
  • localidad : Location
  • municipio : Municipality
  • x : Longitude
  • y : Latitude
  • timedate <S3: POSIXct> : eg. 2014-10-29 14:10:00
  • clase : Class [choque = shock; atropello = ; otro = ; caida de ocupante = ]
# The data is for one year (2014). If we want to filter by month (etc), need a `month` variable first. Choose to use **lubridate** (because we have `timedate`). Could instead `separate()` the `fecha_ocurrencia` (and) and `hora_occurencia` (time) fields into components, but there are 9 rows where `hora_occurencia` says "1899-12-30" (instead of 00:00:00, that `timedate` says), and we'd have to filter/edit those
accidents <- accidents_raw %>%
    filter(year(timedate) == 2014)            # 18 rows from 2013 filtered out
accidents                                     # (9982 rows x 13 cols)

Basic EDA

# Just to get a sense of what's going on
accidents %>% count(the_geom)            # 6924 rows (not unique, some accidents at same x&y)
accidents %>% count(the_geom) %>% count(n)  # 21 rows (1 to 22, without 18)
accidents %>% count(cartodb_id)          # 9982 rows (unique)
accidents %>% count(codigo_accidente)    # 9982 rows (unique). ~5e+05 (?) or 4e+06 (`objectid`)
accidents %>% count(month(timedate))     # 12 rows. `n` is 485-1584. Higher in Oct/Nov/Dec
accidents %>% count(hour(timedate))      # 24 rows. `n` is 51-722 (2am, 2pm)
accidents %>% count(gravedad)            # 3 rows. "CON HERIDOS", "CON MUERTOS", "SOLO DANOS"
accidents %>% count(objectid)            # 9982 rows (unique)
accidents %>% count(localidad)           # 19 rows. `n` is 52-1177
accidents %>% count(municipio)           # 1 row ("BOGOTA"). `n` is 9982 --> IGNORE
accidents %>% count(clase)               # 7 rows. `n` is 1 ("INCENDIO") to 8502 ("CHOQUE")

Initial data visialisation, to see if there might be a location/ time pattern

accidents <- accidents %>%
  mutate(week_no = week(timedate), week_day = wday(timedate, label = TRUE))
#1
accidents %>%
  group_by(yday = yday(timedate)) %>%
  summarise(count = n()) %>%
  ggplot(aes(yday, count)) +                           # 'day of the year' (0:1Jan to 365:31Dec)
  geom_point() +
  geom_smooth()

#2
accidents %>%
  filter(month(timedate) == 1) %>%
  group_by(yday = yday(timedate)) %>%
  summarise(count = n()) %>%
  ggplot(aes(yday, count)) +                           # 'day of the year' (0:1Jan to 365:31Dec)
  geom_point() +
  geom_smooth()

#3
ggplot(accidents, aes(timedate)) +
  geom_histogram() +
  facet_wrap(~ localidad)

#4
ggplot(accidents, aes(x, y, colour = localidad)) +     # rough map of the 'localidads'
  geom_point()

Maybe look at a time-based model (especially if there is data for other years too, in which case start with localidad=ENGATIVA). And/or a visualisation (like ACotgreave? if I can get week#). Or time of day (model/viz). Or connected to streetlights (if there’s a joining field)

# Weeks (`week_no`)
accidents %>%
  group_by(week_no, week_day) %>%
  summarise(count = n()) %>%
  ggplot(aes(week_no, week_day)) +
  geom_point(aes(colour = count, size = count, alpha = 0.5))

accidents %>%
  group_by(week_no) %>%
  summarise(count = n()) %>%
  ggplot(aes(week_no, count)) +
  geom_point() +
  geom_smooth()

accidents %>%
  group_by(week_no) %>%
  summarise(count = n()) %>%
  ggplot(aes(week_no, count)) +
  geom_line()

# Hours
#1
accidents %>%
  group_by(week_day, hour = hour(timedate)) %>%
  summarise(count = n()) %>%
  ggplot(aes(hour, week_day)) +
  geom_point(aes(colour = count, size = count, alpha = 0.5))

#2
accidents %>%
  group_by(hour = hour(timedate)) %>%
  summarise(count = n()) %>%
  ggplot(aes(hour)) +
  geom_density()                             

# accidents %>%
#   group_by(hour = hour(timedate)) %>%
#   summarise(count = n()) %>%
#   ggplot(aes(hour)) +
#   geom_density(aes(colour = week_day)) +            # "object 'week_day' not found" ?
#   facet_wrap(~ week_day) # "Error in combine_vars(data, params$plot_env, vars, drop = params$drop) : At least one layer must contain all variables used for facetting" ?"
#3
accidents %>%
  group_by(week_day, hour = hour(timedate)) %>%
  summarise(count = n()) %>%
  ggplot(aes(hour, count)) +
  geom_line(aes(colour = week_day)) +
  facet_wrap(~ week_day)

# Localidads
accidents4 <- accidents %>%
  group_by(month = month(timedate), week_day, hour = hour(timedate), localidad) %>%
  summarise(count = n())
#1
ggplot(accidents4, aes(hour)) +
  geom_density() +
  facet_wrap(~ localidad)

#2
ggplot(accidents4, aes(hour)) +
  geom_density(aes(colour = week_day)) +
  facet_wrap(~ localidad)

#3
ggplot(accidents4, aes(hour)) +
  geom_density() +
  facet_wrap(~ month)

#4
ggplot(accidents4, aes(hour)) +
  geom_density() +
  facet_grid(localidad ~ month)

#5
accidents4 %>%
  filter(localidad == "ENGATIVA") %>%
  ggplot(aes(hour)) +
  geom_density() +
  facet_wrap(~ month)

#6
accidents4 %>%
  filter(localidad == "ENGATIVA") %>%
  ggplot(aes(hour)) +
  geom_density(aes(fill = month)) +
  facet_grid(month ~ .)

Doesn’t appear to be a ‘strong enough’ repeating pattern in 2014, to make it interesting to fit a model to it with modelr. And have been unable to ‘union’ 2014 with the similar-ish 2015&2016 datasets I downloaded, (using Tableau Maestro beta 4), to see if patterns are repeated year-on-year.

So forget about a model and look at the ‘Street Lights’ dataset, to see if that ‘sheds any light’ on (location) patterns in the accidents

lights_raw <- read_csv("data/Street_Lights.csv")
Parsed with column specification:
cols(
  the_geom = col_character(),
  cartodb_id = col_integer(),
  x = col_double(),
  y = col_double(),
  codid = col_integer(),
  direccion = col_character(),
  localidad = col_character(),
  tipointer = col_character(),
  disppdm = col_character(),
  fechaimplementacion = col_date(format = "")
)
lights_raw
#1
ggplot(lights_raw, aes(x, y, colour = localidad)) +     # rough map of the 'localidads'
  geom_point()

#2
ggplot(data=lights_raw, aes(x, y)) +
  geom_point(aes(shape = "."), colour = "red") +
  geom_point(data=accidents, aes(shape = ".", stroke = 0, alpha = 0.5), colour = "black")

#3
accidents_ENGATIVA <- accidents %>%
  filter(localidad == "ENGATIVA")
lights_ENGATIVA <- lights_raw %>%
  filter(localidad == "ENGATIVA")
ggplot(data=lights_ENGATIVA, aes(x, y)) +
  geom_point(aes(shape = "."), size = 3, colour = "black") +
  geom_point(data=accidents_ENGATIVA, aes(shape = ".", stroke = 0, alpha = 0.5), colour = "blue")

#4
deaths_ENGATIVA <- accidents %>%
  filter(localidad == "ENGATIVA") %>%
  filter(gravedad == "CON MUERTOS")
lights_ENGATIVA <- lights_raw %>%
  filter(localidad == "ENGATIVA")
ggplot(data=lights_ENGATIVA, aes(x, y)) +
  geom_point(aes(shape = "."), size = 3, colour = "black") +
  geom_point(data=deaths_ENGATIVA, aes(shape = ".", stroke = 0), size = 2, colour = "red")

There are more accident locations in ENGATIVA than there are street lights. And although some of those street lights have no accidents next to them (including clusters in the SouthEast), the majority does have. So it’s not as simple as saying the patterns are connected (let alone that street lights prevent accidents)

However, only 3 of 11 deaths was next to a street light (in areas where other accidents were happening), so that’s a slightly stronger (visual) case that the lights have a positive effect

LS0tCnRpdGxlOiAiQm9nb3RhIGNhciBhY2NpZGVudHMgMjAxNCIKb3V0cHV0OgogIGdpdGh1Yl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgojIEJvZ290YSBjYXIgYWNjaWRlbnRzIDIwMTQKCmBgYHtyIHNldHVwfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsdWJyaWRhdGUpCmBgYAoKCiMjIERhdGEgaW1wb3J0CgpEYXRhIGRvd25sb2FkZWQgZnJvbSBodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xbGdSLVVwUjl2OWxtdG9lSzFaaGxWZnMwRkJqMXhYel9lSW1oY3JTSTRRMC8KCmBgYHtyfQphY2NpZGVudHNfcmF3IDwtIHJlYWRfY3N2KCJkYXRhL0Nhcl9BY2NpZGVudHNfMjAxNF9Cb2dvdGEuY3N2IikKYWNjaWRlbnRzX3JhdwoKIyBPZGQgdG8gaGF2ZSBleGFjdGx5IDEwMDAwIHJvd3MsIGlmIHRoZSBkYXRhc2V0IGlzIHN1cHBvc2VkIHRvIGJlIGNvbXBsZXRlCmBgYAoKKiBgdGhlX2dlb21gIDxjaHI+IDogZ2VvbQoqIGBjYXJ0b2RiX2lkYCA8aW50PiA6IHJlZmVyZW5jZSMKKiBgY29kaWdvX2FjY2lkZW50ZWAgPGludD4gOiBBY2NpZGVudCBjb2RlIGZyb20gcG9saWNlID8KKiBgZmVjaGFfb2N1cnJlbmNpYWAgPGRhdGU+IGVnLiAyMDE0LTEwLTI5IDogRGF0ZQoqIGBob3JhX29jY3VyZW5jaWFgIDxjaHI+ICAgZWcuIDE0OjEwOjAwIDogVGltZQoqIGBncmF2ZWRhZGAgPGNocj4gOiBHcmF2aXR5IChzZXZlcml0eSkKKiBgb2JqZWN0aWRgIDxpbnQ+IDogcmVmZXJlbmNlIwoqIGBsb2NhbGlkYWRgIDxjaHI+IDogTG9jYXRpb24KKiBgbXVuaWNpcGlvYCA8Y2hyPiA6IE11bmljaXBhbGl0eQoqIGB4YCA8ZGJsPiA6IExvbmdpdHVkZQoqIGB5YCA8ZGJsPiA6IExhdGl0dWRlCiogYHRpbWVkYXRlYCA8UzM6IFBPU0lYY3Q+IDogZWcuIDIwMTQtMTAtMjkgMTQ6MTA6MDAKKiBgY2xhc2VgIDxjaHI+IDogQ2xhc3MgW2Nob3F1ZSA9IHNob2NrOyBhdHJvcGVsbG8gPSA7IG90cm8gPSA7IGNhaWRhIGRlIG9jdXBhbnRlID0gXQoKCgoKYGBge3J9CiMgVGhlIGRhdGEgaXMgZm9yIG9uZSB5ZWFyICgyMDE0KS4gSWYgd2Ugd2FudCB0byBmaWx0ZXIgYnkgbW9udGggKGV0YyksIG5lZWQgYSBgbW9udGhgIHZhcmlhYmxlIGZpcnN0LiBDaG9vc2UgdG8gdXNlICoqbHVicmlkYXRlKiogKGJlY2F1c2Ugd2UgaGF2ZSBgdGltZWRhdGVgKS4gQ291bGQgaW5zdGVhZCBgc2VwYXJhdGUoKWAgdGhlIGBmZWNoYV9vY3VycmVuY2lhYCAoYW5kKSBhbmQgYGhvcmFfb2NjdXJlbmNpYWAgKHRpbWUpIGZpZWxkcyBpbnRvIGNvbXBvbmVudHMsIGJ1dCB0aGVyZSBhcmUgOSByb3dzIHdoZXJlIGBob3JhX29jY3VyZW5jaWFgIHNheXMgIjE4OTktMTItMzAiIChpbnN0ZWFkIG9mIDAwOjAwOjAwLCB0aGF0IGB0aW1lZGF0ZWAgc2F5cyksIGFuZCB3ZSdkIGhhdmUgdG8gZmlsdGVyL2VkaXQgdGhvc2UKCmFjY2lkZW50cyA8LSBhY2NpZGVudHNfcmF3ICU+JQogICAgZmlsdGVyKHllYXIodGltZWRhdGUpID09IDIwMTQpICAgICAgICAgICAgIyAxOCByb3dzIGZyb20gMjAxMyBmaWx0ZXJlZCBvdXQKCmFjY2lkZW50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICg5OTgyIHJvd3MgeCAxMyBjb2xzKQpgYGAKCgojIyBCYXNpYyBFREEKCmBgYHtyfQojIEp1c3QgdG8gZ2V0IGEgc2Vuc2Ugb2Ygd2hhdCdzIGdvaW5nIG9uCgphY2NpZGVudHMgJT4lIGNvdW50KHRoZV9nZW9tKSAgICAgICAgICAgICMgNjkyNCByb3dzIChub3QgdW5pcXVlLCBzb21lIGFjY2lkZW50cyBhdCBzYW1lIHgmeSkKYWNjaWRlbnRzICU+JSBjb3VudCh0aGVfZ2VvbSkgJT4lIGNvdW50KG4pICAjIDIxIHJvd3MgKDEgdG8gMjIsIHdpdGhvdXQgMTgpCmFjY2lkZW50cyAlPiUgY291bnQoY2FydG9kYl9pZCkgICAgICAgICAgIyA5OTgyIHJvd3MgKHVuaXF1ZSkKYWNjaWRlbnRzICU+JSBjb3VudChjb2RpZ29fYWNjaWRlbnRlKSAgICAjIDk5ODIgcm93cyAodW5pcXVlKS4gfjVlKzA1ICg/KSBvciA0ZSswNiAoYG9iamVjdGlkYCkKYWNjaWRlbnRzICU+JSBjb3VudChtb250aCh0aW1lZGF0ZSkpICAgICAjIDEyIHJvd3MuIGBuYCBpcyA0ODUtMTU4NC4gSGlnaGVyIGluIE9jdC9Ob3YvRGVjCmFjY2lkZW50cyAlPiUgY291bnQoaG91cih0aW1lZGF0ZSkpICAgICAgIyAyNCByb3dzLiBgbmAgaXMgNTEtNzIyICgyYW0sIDJwbSkKYWNjaWRlbnRzICU+JSBjb3VudChncmF2ZWRhZCkgICAgICAgICAgICAjIDMgcm93cy4gIkNPTiBIRVJJRE9TIiwgIkNPTiBNVUVSVE9TIiwgIlNPTE8gREFOT1MiCmFjY2lkZW50cyAlPiUgY291bnQob2JqZWN0aWQpICAgICAgICAgICAgIyA5OTgyIHJvd3MgKHVuaXF1ZSkKYWNjaWRlbnRzICU+JSBjb3VudChsb2NhbGlkYWQpICAgICAgICAgICAjIDE5IHJvd3MuIGBuYCBpcyA1Mi0xMTc3CmFjY2lkZW50cyAlPiUgY291bnQobXVuaWNpcGlvKSAgICAgICAgICAgIyAxIHJvdyAoIkJPR09UQSIpLiBgbmAgaXMgOTk4MiAtLT4gSUdOT1JFCmFjY2lkZW50cyAlPiUgY291bnQoY2xhc2UpICAgICAgICAgICAgICAgIyA3IHJvd3MuIGBuYCBpcyAxICgiSU5DRU5ESU8iKSB0byA4NTAyICgiQ0hPUVVFIikKYGBgCgpJbml0aWFsIGRhdGEgdmlzaWFsaXNhdGlvbiwgdG8gc2VlIGlmIHRoZXJlIG1pZ2h0IGJlIGEgbG9jYXRpb24vIHRpbWUgcGF0dGVybgoKYGBge3J9CmFjY2lkZW50cyA8LSBhY2NpZGVudHMgJT4lCiAgbXV0YXRlKHdlZWtfbm8gPSB3ZWVrKHRpbWVkYXRlKSwgd2Vla19kYXkgPSB3ZGF5KHRpbWVkYXRlLCBsYWJlbCA9IFRSVUUpKQoKIzEKYWNjaWRlbnRzICU+JQogIGdyb3VwX2J5KHlkYXkgPSB5ZGF5KHRpbWVkYXRlKSkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUKICBnZ3Bsb3QoYWVzKHlkYXksIGNvdW50KSkgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICMgJ2RheSBvZiB0aGUgeWVhcicgKDA6MUphbiB0byAzNjU6MzFEZWMpCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aCgpCgojMgphY2NpZGVudHMgJT4lCiAgZmlsdGVyKG1vbnRoKHRpbWVkYXRlKSA9PSAxKSAlPiUKICBncm91cF9ieSh5ZGF5ID0geWRheSh0aW1lZGF0ZSkpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh5ZGF5LCBjb3VudCkpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAjICdkYXkgb2YgdGhlIHllYXInICgwOjFKYW4gdG8gMzY1OjMxRGVjKQogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoKQoKIzMKZ2dwbG90KGFjY2lkZW50cywgYWVzKHRpbWVkYXRlKSkgKwogIGdlb21faGlzdG9ncmFtKCkgKwogIGZhY2V0X3dyYXAofiBsb2NhbGlkYWQpCgojNApnZ3Bsb3QoYWNjaWRlbnRzLCBhZXMoeCwgeSwgY29sb3VyID0gbG9jYWxpZGFkKSkgKyAgICAgIyByb3VnaCBtYXAgb2YgdGhlICdsb2NhbGlkYWRzJwogIGdlb21fcG9pbnQoKQpgYGAKCgpNYXliZSBsb29rIGF0IGEgdGltZS1iYXNlZCBtb2RlbCAoZXNwZWNpYWxseSBpZiB0aGVyZSBpcyBkYXRhIGZvciBvdGhlciB5ZWFycyB0b28sIGluIHdoaWNoIGNhc2Ugc3RhcnQgd2l0aCBsb2NhbGlkYWQ9RU5HQVRJVkEpLiBBbmQvb3IgYSB2aXN1YWxpc2F0aW9uIChsaWtlIEFDb3RncmVhdmU/IGlmIEkgY2FuIGdldCB3ZWVrIykuIE9yIHRpbWUgb2YgZGF5IChtb2RlbC92aXopLiBPciBjb25uZWN0ZWQgdG8gc3RyZWV0bGlnaHRzIChpZiB0aGVyZSdzIGEgam9pbmluZyBmaWVsZCkKCmBgYHtyfQojIFdlZWtzIChgd2Vla19ub2ApCgojMQphY2NpZGVudHMgJT4lCiAgZ3JvdXBfYnkod2Vla19ubywgd2Vla19kYXkpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh3ZWVrX25vLCB3ZWVrX2RheSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBjb3VudCwgc2l6ZSA9IGNvdW50LCBhbHBoYSA9IDAuNSkpCgojMgphY2NpZGVudHMgJT4lCiAgZ3JvdXBfYnkod2Vla19ubykgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUKICBnZ3Bsb3QoYWVzKHdlZWtfbm8sIGNvdW50KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoKQoKIzMKYWNjaWRlbnRzICU+JQogIGdyb3VwX2J5KHdlZWtfbm8pICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh3ZWVrX25vLCBjb3VudCkpICsKICBnZW9tX2xpbmUoKQpgYGAKCgpgYGB7cn0KIyBIb3VycwoKIzEKYWNjaWRlbnRzICU+JQogIGdyb3VwX2J5KHdlZWtfZGF5LCBob3VyID0gaG91cih0aW1lZGF0ZSkpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyhob3VyLCB3ZWVrX2RheSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBjb3VudCwgc2l6ZSA9IGNvdW50LCBhbHBoYSA9IDAuNSkpCgojMgphY2NpZGVudHMgJT4lCiAgZ3JvdXBfYnkoaG91ciA9IGhvdXIodGltZWRhdGUpKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQogIGdncGxvdChhZXMoaG91cikpICsKICBnZW9tX2RlbnNpdHkoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgojIGFjY2lkZW50cyAlPiUKIyAgIGdyb3VwX2J5KGhvdXIgPSBob3VyKHRpbWVkYXRlKSkgJT4lCiMgICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQojICAgZ2dwbG90KGFlcyhob3VyKSkgKwojICAgZ2VvbV9kZW5zaXR5KGFlcyhjb2xvdXIgPSB3ZWVrX2RheSkpICsgICAgICAgICAgICAjICJvYmplY3QgJ3dlZWtfZGF5JyBub3QgZm91bmQiID8KIyAgIGZhY2V0X3dyYXAofiB3ZWVrX2RheSkgIyAiRXJyb3IgaW4gY29tYmluZV92YXJzKGRhdGEsIHBhcmFtcyRwbG90X2VudiwgdmFycywgZHJvcCA9IHBhcmFtcyRkcm9wKSA6IEF0IGxlYXN0IG9uZSBsYXllciBtdXN0IGNvbnRhaW4gYWxsIHZhcmlhYmxlcyB1c2VkIGZvciBmYWNldHRpbmciID8iCgojMwphY2NpZGVudHMgJT4lCiAgZ3JvdXBfYnkod2Vla19kYXksIGhvdXIgPSBob3VyKHRpbWVkYXRlKSkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUKICBnZ3Bsb3QoYWVzKGhvdXIsIGNvdW50KSkgKwogIGdlb21fbGluZShhZXMoY29sb3VyID0gd2Vla19kYXkpKSArCiAgZmFjZXRfd3JhcCh+IHdlZWtfZGF5KQpgYGAKCgpgYGB7cn0KIyBMb2NhbGlkYWRzCgphY2NpZGVudHM0IDwtIGFjY2lkZW50cyAlPiUKICBncm91cF9ieShtb250aCA9IG1vbnRoKHRpbWVkYXRlKSwgd2Vla19kYXksIGhvdXIgPSBob3VyKHRpbWVkYXRlKSwgbG9jYWxpZGFkKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpCgojMQpnZ3Bsb3QoYWNjaWRlbnRzNCwgYWVzKGhvdXIpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofiBsb2NhbGlkYWQpCgojMgpnZ3Bsb3QoYWNjaWRlbnRzNCwgYWVzKGhvdXIpKSArCiAgZ2VvbV9kZW5zaXR5KGFlcyhjb2xvdXIgPSB3ZWVrX2RheSkpICsKICBmYWNldF93cmFwKH4gbG9jYWxpZGFkKQoKIzMKZ2dwbG90KGFjY2lkZW50czQsIGFlcyhob3VyKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH4gbW9udGgpCgojNApnZ3Bsb3QoYWNjaWRlbnRzNCwgYWVzKGhvdXIpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X2dyaWQobG9jYWxpZGFkIH4gbW9udGgpCgojNQphY2NpZGVudHM0ICU+JQogIGZpbHRlcihsb2NhbGlkYWQgPT0gIkVOR0FUSVZBIikgJT4lCiAgZ2dwbG90KGFlcyhob3VyKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH4gbW9udGgpCgojNgphY2NpZGVudHM0ICU+JQogIGZpbHRlcihsb2NhbGlkYWQgPT0gIkVOR0FUSVZBIikgJT4lCiAgZ2dwbG90KGFlcyhob3VyKSkgKwogIGdlb21fZGVuc2l0eShhZXMoZmlsbCA9IG1vbnRoKSkgKwogIGZhY2V0X2dyaWQobW9udGggfiAuKQpgYGAKCgoKRG9lc24ndCBhcHBlYXIgdG8gYmUgYSAnc3Ryb25nIGVub3VnaCcgcmVwZWF0aW5nIHBhdHRlcm4gaW4gMjAxNCwgdG8gbWFrZSBpdCBpbnRlcmVzdGluZyB0byBmaXQgYSBtb2RlbCB0byBpdCB3aXRoICoqbW9kZWxyKiouIEFuZCBoYXZlIGJlZW4gdW5hYmxlIHRvICd1bmlvbicgMjAxNCB3aXRoIHRoZSBzaW1pbGFyLWlzaCAyMDE1JjIwMTYgZGF0YXNldHMgSSBkb3dubG9hZGVkLCAodXNpbmcgVGFibGVhdSBNYWVzdHJvIGJldGEgNCksIHRvIHNlZSBpZiBwYXR0ZXJucyBhcmUgcmVwZWF0ZWQgeWVhci1vbi15ZWFyLgoKU28gZm9yZ2V0IGFib3V0IGEgbW9kZWwgYW5kIGxvb2sgYXQgdGhlICdTdHJlZXQgTGlnaHRzJyBkYXRhc2V0LCB0byBzZWUgaWYgdGhhdCAnc2hlZHMgYW55IGxpZ2h0JyBvbiAobG9jYXRpb24pIHBhdHRlcm5zIGluIHRoZSBhY2NpZGVudHMKCmBgYHtyfQpsaWdodHNfcmF3IDwtIHJlYWRfY3N2KCJkYXRhL1N0cmVldF9MaWdodHMuY3N2IikKbGlnaHRzX3JhdwpgYGAKCgoKCmBgYHtyfQojMQpnZ3Bsb3QobGlnaHRzX3JhdywgYWVzKHgsIHksIGNvbG91ciA9IGxvY2FsaWRhZCkpICsgICAgICMgcm91Z2ggbWFwIG9mIHRoZSAnbG9jYWxpZGFkcycKICBnZW9tX3BvaW50KCkKCiMyCmdncGxvdChkYXRhPWxpZ2h0c19yYXcsIGFlcyh4LCB5KSkgKwogIGdlb21fcG9pbnQoYWVzKHNoYXBlID0gIi4iKSwgY29sb3VyID0gInJlZCIpICsKICBnZW9tX3BvaW50KGRhdGE9YWNjaWRlbnRzLCBhZXMoc2hhcGUgPSAiLiIsIHN0cm9rZSA9IDAsIGFscGhhID0gMC41KSwgY29sb3VyID0gImJsYWNrIikKCiMzCmFjY2lkZW50c19FTkdBVElWQSA8LSBhY2NpZGVudHMgJT4lCiAgZmlsdGVyKGxvY2FsaWRhZCA9PSAiRU5HQVRJVkEiKQoKbGlnaHRzX0VOR0FUSVZBIDwtIGxpZ2h0c19yYXcgJT4lCiAgZmlsdGVyKGxvY2FsaWRhZCA9PSAiRU5HQVRJVkEiKQoKZ2dwbG90KGRhdGE9bGlnaHRzX0VOR0FUSVZBLCBhZXMoeCwgeSkpICsKICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9ICIuIiksIHNpemUgPSAzLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChkYXRhPWFjY2lkZW50c19FTkdBVElWQSwgYWVzKHNoYXBlID0gIi4iLCBzdHJva2UgPSAwLCBhbHBoYSA9IDAuNSksIGNvbG91ciA9ICJibHVlIikKCiM0CmRlYXRoc19FTkdBVElWQSA8LSBhY2NpZGVudHMgJT4lCiAgZmlsdGVyKGxvY2FsaWRhZCA9PSAiRU5HQVRJVkEiKSAlPiUKICBmaWx0ZXIoZ3JhdmVkYWQgPT0gIkNPTiBNVUVSVE9TIikKCmxpZ2h0c19FTkdBVElWQSA8LSBsaWdodHNfcmF3ICU+JQogIGZpbHRlcihsb2NhbGlkYWQgPT0gIkVOR0FUSVZBIikKCmdncGxvdChkYXRhPWxpZ2h0c19FTkdBVElWQSwgYWVzKHgsIHkpKSArCiAgZ2VvbV9wb2ludChhZXMoc2hhcGUgPSAiLiIpLCBzaXplID0gMywgY29sb3VyID0gImJsYWNrIikgKwogIGdlb21fcG9pbnQoZGF0YT1kZWF0aHNfRU5HQVRJVkEsIGFlcyhzaGFwZSA9ICIuIiwgc3Ryb2tlID0gMCksIHNpemUgPSAyLCBjb2xvdXIgPSAicmVkIikKYGBgCgpUaGVyZSBhcmUgbW9yZSBhY2NpZGVudCBsb2NhdGlvbnMgaW4gRU5HQVRJVkEgdGhhbiB0aGVyZSBhcmUgc3RyZWV0IGxpZ2h0cy4gQW5kIGFsdGhvdWdoIHNvbWUgb2YgdGhvc2Ugc3RyZWV0IGxpZ2h0cyBoYXZlIG5vIGFjY2lkZW50cyBuZXh0IHRvIHRoZW0gKGluY2x1ZGluZyBjbHVzdGVycyBpbiB0aGUgU291dGhFYXN0KSwgdGhlIG1ham9yaXR5IGRvZXMgaGF2ZS4gU28gaXQncyBub3QgYXMgc2ltcGxlIGFzIHNheWluZyB0aGUgcGF0dGVybnMgYXJlIGNvbm5lY3RlZCAobGV0IGFsb25lIHRoYXQgc3RyZWV0IGxpZ2h0cyBwcmV2ZW50IGFjY2lkZW50cykKCkhvd2V2ZXIsIG9ubHkgMyBvZiAxMSBkZWF0aHMgd2FzIG5leHQgdG8gYSBzdHJlZXQgbGlnaHQgKGluIGFyZWFzIHdoZXJlIG90aGVyIGFjY2lkZW50cyB3ZXJlIGhhcHBlbmluZyksIHNvIHRoYXQncyBhIHNsaWdodGx5IHN0cm9uZ2VyICh2aXN1YWwpIGNhc2UgdGhhdCB0aGUgbGlnaHRzIGhhdmUgYSBwb3NpdGl2ZSBlZmZlY3QKCgo=